package org.softee.functional.operation;

import java.util.Map;

public class Functions {
    private Functions() {
    }

    /**
     * @return a function that returns the length of the input string (or null the string is null)
     */
    public static Function<String, Integer> stringLength() {
        return new Function<String, Integer>() {
            @Override
            public Integer apply(String input) {
                return (input != null) ? input.length() : null;
            }
        };
    }

    public static <F, T> Function<F, T> forMap(final Map<F, T> map, final T defaultValue) {
        return new Function<F, T>() {
            @Override
            public T apply(F input) {
                if (map.containsKey(input)) {
                    return map.get(input);
                } else {
                    return defaultValue;
                }
            }
        };
    }

    public static <F, X, T> Function<F, T> compound(final Function<F, X> f1, final Function<X, T> f2) {
        return new Function<F, T>() {
            @Override
            public T apply(F input) {
                return f2.apply(f1.apply(input));
            }
        };
    }

    public static <T> Function<T, T> identity() {
        return new Function<T, T>() {
            @Override
            public T apply(T input) {
                return input;
            }
        };
    }

    public static <T> Function<T, T> identityDefault(final T defaultValue) {
        return new Function<T, T>() {
            @Override
            public T apply(T input) {
                return (input != null) ? input : defaultValue;
            }
        };
    }
}
